﻿using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;

namespace JY.Wpf.Controls.Behaviors
{
    /// <summary>
    /// ListBox多选Behavior
    /// </summary>
    public class ListBoxMultiSelectBehavior : Behavior<ListBox>
    {
        private ListBox ListBox
        {
            get
            {
                return this.AssociatedObject as ListBox;
            }
        }

        public INotifyCollectionChanged SelectedItems
        {
            get { return (INotifyCollectionChanged)this.GetValue(SelectedItemsProperty); }
            set { this.SetValue(SelectedItemsProperty, value); }
        }

        public static readonly DependencyProperty SelectedItemsProperty =
            DependencyProperty.Register("SelectedItems", typeof(INotifyCollectionChanged), typeof(ListBoxMultiSelectBehavior), new PropertyMetadata(OnSelectedItemsPropertyChanged));


        private static void OnSelectedItemsPropertyChanged(DependencyObject target, DependencyPropertyChangedEventArgs args)
        {
            var collection = args.NewValue as INotifyCollectionChanged;
            if (collection != null)
            {
                collection.CollectionChanged += ((ListBoxMultiSelectBehavior)target).ContextSelectedItems_CollectionChanged;
            }
        }

        protected override void OnAttached()
        {
            base.OnAttached();

            this.ListBox.SelectionChanged += this.ListBoxSelectedItems_CollectionChanged;
        }
        void ContextSelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            this.UnsubscribeFromEvents();

            Transfer(this.SelectedItems as IList, this.ListBox.SelectedItems);

            this.SubscribeToEvents();
        }

        void ListBoxSelectedItems_CollectionChanged(object sender, SelectionChangedEventArgs e)
        {
            this.UnsubscribeFromEvents();

            Transfer(this.ListBox.SelectedItems, this.SelectedItems as IList);

            this.SubscribeToEvents();
        }

        private void SubscribeToEvents()
        {
            this.ListBox.SelectionChanged += this.ListBoxSelectedItems_CollectionChanged;

            if (this.SelectedItems != null)
            {
                this.SelectedItems.CollectionChanged += this.ContextSelectedItems_CollectionChanged;
            }
        }

        private void UnsubscribeFromEvents()
        {
            this.ListBox.SelectionChanged -= this.ListBoxSelectedItems_CollectionChanged;

            if (this.SelectedItems != null)
            {
                this.SelectedItems.CollectionChanged -= this.ContextSelectedItems_CollectionChanged;
            }
        }

        public static void Transfer(IList source, IList target)
        {
            if (source == null || target == null)
                return;

            target.Clear();

            foreach (var o in source)
            {
                target.Add(o);
            }
        }
    }
}
